﻿using BCCommon;
using BCCommon.Enums;
using BCData.TMS.VehicleSuiteBusinessConfig;
using BCDto.TMS.VehicleSuiteBusinessConfig;
using BCEntity.TMS.VehicleSuiteBusinessConfig;
using BCEntity.Common.EntityNameConst;
using BCService.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BCDto.Sim.Admin.Admin;
using BCService.Common.Area;
using BCService.TMS.Agent.AgentAreaRecord;
using BCCommon.Extensions;
using BCCommon.TMS.Transport;
using BCData.TMS.VehicleTransportBusinessConfig;
using BCService.TMS.WorryFreeMoveSuiteConfig;
using BCService.TMS.EasyMoveSuiteConfig;

namespace BCService.TMS.VehicleSuiteBusinessConfig
{
    public class VehicleSuiteBusinessConfigService : IVehicleSuiteBusinessConfigService
    {
        private readonly IDatabaseContext databaseContext;
        private readonly IRedisService redisService;
        private readonly IVehicleTransportBusinessConfigData vehicleTransportBusinessConfigData;
        private readonly IVehicleSuiteBusinessConfigData vehicleSuiteBusinessConfigData;
        private readonly IWorryFreeMoveSuiteConfigService worryFreeMoveSuiteConfigService;
        private readonly IEasyMoveSuiteConfigService easyMoveSuiteConfigService;
        private readonly IAgentAreaRecordService agentAreaRecordService;
        private readonly IZoneService zoneService;
        private readonly string key = string.Format("{0}", EntityNameConst.VehicleSuiteBusinessConfigEntity);

        public VehicleSuiteBusinessConfigService(IDatabaseContext databaseContext,
            IRedisService redisService,
            IVehicleTransportBusinessConfigData vehicleTransportBusinessConfigData,
            IVehicleSuiteBusinessConfigData vehicleSuiteBusinessConfigData,
            IWorryFreeMoveSuiteConfigService worryFreeMoveSuiteConfigService,
            IEasyMoveSuiteConfigService easyMoveSuiteConfigService,
            IAgentAreaRecordService agentAreaRecordService,
            IZoneService zoneService)
        {
            this.databaseContext = databaseContext;
            this.redisService = redisService;
            this.vehicleTransportBusinessConfigData = vehicleTransportBusinessConfigData;
            this.vehicleSuiteBusinessConfigData = vehicleSuiteBusinessConfigData;
            this.worryFreeMoveSuiteConfigService = worryFreeMoveSuiteConfigService;
            this.easyMoveSuiteConfigService = easyMoveSuiteConfigService;
            this.agentAreaRecordService = agentAreaRecordService;
            this.zoneService = zoneService;
        }

        #region 检查车辆套餐业务配置是否存在
        public bool Exists(int vehicleSuiteBusinessConfigId)
        {
            return this.vehicleSuiteBusinessConfigData.Exists(vehicleSuiteBusinessConfigId).GetAwaiter().GetResult();
        }
        #endregion

        #region 添加车辆套餐业务配置
        public VehicleSuiteBusinessConfigDto Add(AdminDto adminDto, VehicleSuiteBusinessConfigRequestDto requestDto)
        {
            if (adminDto.AgentRecord == null)
            {
                throw new ArgumentException("非代理商无需操作!");
            }
            var transportBusinessEntity = this.vehicleTransportBusinessConfigData.GetByTransportBusiness(requestDto.TransportBusiness).Result;
            if (transportBusinessEntity == null)
            {
                throw new ArgumentException("此业务不存在!");
            }
            if (this.vehicleSuiteBusinessConfigData.Exists(transportBusinessEntity.VehicleTransportBusinessConfigId,requestDto.SuiteBusinessType,requestDto.CountyCode, adminDto.AgentRecord.AgentRecordId).GetAwaiter().GetResult())
            {
                throw new ArgumentException("此记录已存在!");
            }
            var zoneEntity = this.zoneService.GetFromZoneEntity(requestDto.CountyCode);
            if (zoneEntity == null || zoneEntity.countyEntity == null || zoneEntity.provinceEntity == null || zoneEntity.cityEntity == null)
            {
                throw new ArgumentException("此区县编码不正确");
            }
            if (!this.agentAreaRecordService.CheckCountyAuthorize(zoneEntity.countyEntity.CountyCode, adminDto.AgentRecord.AgentRecordId))
            {
                throw new ArgumentException("此区域授权失败!");
            }

            if (requestDto.SourceFee < requestDto.CurrentlyFee)
            {
                throw new ArgumentException("原价应小于现价!");
            }
            var entity = requestDto.As<VehicleSuiteBusinessConfigEntity>();
            entity.CreateAdminName = adminDto.FullName;
            entity.CreateAdminId = adminDto.AdminId;
            entity.VehicleTransportBusinessConfigId = transportBusinessEntity.VehicleTransportBusinessConfigId;
            entity.ProvinceCode = zoneEntity.provinceEntity.ProvinceCode;
            entity.CityCode = zoneEntity.cityEntity.CityCode;
            entity.SuiteBusinessName = entity.SuiteBusinessType.GetDescriptionString();
            entity.AgentRecordId = adminDto.AgentRecord.AgentRecordId;
            return this.vehicleSuiteBusinessConfigData.Add(entity).GetAwaiter().GetResult().As<VehicleSuiteBusinessConfigDto>();
        }
        #endregion

        #region 修改车辆套餐业务配置
        public VehicleSuiteBusinessConfigDto Update(AdminDto adminDto, VehicleSuiteBusinessConfigPutDto putDto)
        {
            if (adminDto.AgentRecord == null)
            {
                throw new ArgumentException("非代理商无需操作!");
            }
            if (!this.Exists(putDto.VehicleSuiteBusinessConfigId))
            {
                throw new ArgumentException("此记录不存在!");
            }
            var transportBusinessEntity = this.vehicleTransportBusinessConfigData.GetByTransportBusiness(putDto.TransportBusiness).Result;
            if (transportBusinessEntity == null)
            {
                throw new ArgumentException("此业务不存在!");
            }
            if (this.vehicleSuiteBusinessConfigData.Exists(transportBusinessEntity.VehicleTransportBusinessConfigId, putDto.SuiteBusinessType, putDto.CountyCode, adminDto.AgentRecord.AgentRecordId).GetAwaiter().GetResult())
            {
                var suiteBusinessConfig = this.vehicleSuiteBusinessConfigData.GetEntity(transportBusinessEntity.VehicleTransportBusinessConfigId, putDto.SuiteBusinessType, putDto.CountyCode, adminDto.AgentRecord.AgentRecordId).Result;
                if(suiteBusinessConfig.VehicleSuiteBusinessConfigId != putDto.VehicleSuiteBusinessConfigId)
                {
                    throw new ArgumentException("此记录已存在!");
                }
            }
            var zoneEntity = this.zoneService.GetFromZoneEntity(putDto.CountyCode);
            if (zoneEntity == null || zoneEntity.countyEntity == null || zoneEntity.provinceEntity == null || zoneEntity.cityEntity == null)
            {
                throw new ArgumentException("此区县编码不正确");
            }
            if (!this.agentAreaRecordService.CheckCountyAuthorize(zoneEntity.countyEntity.CountyCode, adminDto.AgentRecord.AgentRecordId))
            {
                throw new ArgumentException("此区域授权失败!");
            }
            if (putDto.SourceFee < putDto.CurrentlyFee)
            {
                throw new ArgumentException("原价应大于现价!");
            }
            var entity = putDto.As<VehicleSuiteBusinessConfigEntity>();
            entity.EditAdminName = adminDto.FullName;
            entity.EditAdminId = adminDto.AdminId;
            entity.VehicleTransportBusinessConfigId = transportBusinessEntity.VehicleTransportBusinessConfigId;
            entity.ProvinceCode = zoneEntity.provinceEntity.ProvinceCode;
            entity.CityCode = zoneEntity.cityEntity.CityCode;
            entity.SuiteBusinessName = entity.SuiteBusinessType.GetDescriptionString();
            var result = this.vehicleSuiteBusinessConfigData.Update(entity).GetAwaiter().GetResult().As<VehicleSuiteBusinessConfigDto>();
            string cacheKey = this.redisService.GetKey(key, entity.VehicleSuiteBusinessConfigId);
            this.redisService.DeleteAsync(cacheKey);
            return result;
        }
        #endregion

        #region 获取车辆套餐业务配置
        public VehicleSuiteBusinessConfigDto Get(int vehicleSuiteBusinessConfigId)
        {
            string cacheKey = this.redisService.GetKey(key, vehicleSuiteBusinessConfigId);
            var result = this.redisService.TryGet(cacheKey, () =>
            {
                var data = this.vehicleSuiteBusinessConfigData.GetEntity(vehicleSuiteBusinessConfigId).GetAwaiter().GetResult();
                return data;
            }, TimeSpan.FromDays(1));
            return result.As<VehicleSuiteBusinessConfigDto>();
        }
        #endregion

        #region 获取车辆套餐业务配置列表
        public IEnumerable<VehicleSuiteBusinessConfigDto> GetList(long agentRecordId)
        {
            string cacheKey = this.redisService.GetKey(key, agentRecordId);
            var result = this.redisService.TryGet(cacheKey, () =>
            {
                return this.vehicleSuiteBusinessConfigData.GetList(agentRecordId).GetAwaiter().GetResult();
            }, TimeSpan.FromDays(1));
            return result.As<IEnumerable<VehicleSuiteBusinessConfigDto>>();
        }

        public IEnumerable<VehicleSuiteBusinessConfigDto> GetList(long? agentRecordId, string countyCode,int vehicleTransportBusinessConfigId)
        {
            if (!agentRecordId.HasValue)
            {
                return new List<VehicleSuiteBusinessConfigDto>();
            }
            else
            {
                string cacheKey = this.redisService.GetKey(key, agentRecordId, countyCode, vehicleTransportBusinessConfigId);
                var result = this.redisService.TryGet(cacheKey, () =>
                {
                    var list = this.vehicleSuiteBusinessConfigData.GetList(agentRecordId.Value, countyCode, vehicleTransportBusinessConfigId).GetAwaiter().GetResult();
                    foreach (var item in list)
                    {
                        if (item.SuiteBusinessType == VehicleSuiteBusinessType.WorryFreeMove)
                        {
                            var worryFreeList = this.worryFreeMoveSuiteConfigService.GetList(item.AgentRecordId, item.CountyCode);
                            if (worryFreeList.Any())
                            {
                                var worrFreeDto = worryFreeList.OrderBy(p => p.StartPrice).First();
                                item.SourceFee = worrFreeDto.StartPrice + worrFreeDto.CarryServiceAmount;
                                item.CurrentlyFee = worrFreeDto.StartPrice + worrFreeDto.CarryServiceAmount - (worrFreeDto.CouponAmount.HasValue ? worrFreeDto.CouponAmount.Value : 0);
                            }
                        }
                        else
                        {
                            var easyList = this.easyMoveSuiteConfigService.GetList(item.AgentRecordId, item.CountyCode);
                            if (easyList.Any())
                            {
                                var easyDto = easyList.OrderBy(p => p.StartPrice).First();
                                item.SourceFee = easyDto.StartPrice;
                                item.CurrentlyFee = easyDto.StartPrice - (easyDto.CouponAmount.HasValue ? easyDto.CouponAmount.Value : 0);
                            }
                        }
                    }
                    return list;
                }, TimeSpan.FromDays(1));

               

                return result.As<IEnumerable<VehicleSuiteBusinessConfigDto>>();
            }
        }
        #endregion

        #region 获取车辆套餐业务配置分页
        public PageableList<VehicleSuiteBusinessConfigDto> Query(long? agentRecordId, string suiteBusinessName, string provinceCode, string cityCode, string countyCode, VehicleSuiteBusinessType? suiteBusinessType, bool? enabled, DateTime? start, DateTime? end, string sortName, bool? ascending, int pageIndex, int pageSize)
        {
            string cacheKey = this.redisService.GetKey(key, agentRecordId, suiteBusinessName, provinceCode, cityCode,countyCode, suiteBusinessType,enabled, start, end, sortName, ascending, pageIndex, pageSize);
            var result = this.redisService.TryGet(cacheKey, () =>
            {
                var data = this.vehicleSuiteBusinessConfigData.Query(agentRecordId, suiteBusinessName, provinceCode, cityCode, countyCode, suiteBusinessType, enabled, start, end, sortName, ascending, pageIndex, pageSize).GetAwaiter().GetResult();
                return new PageableList<VehicleSuiteBusinessConfigDto>
                {
                    Count = data.Item2,
                    Items = data.Item1.As<IEnumerable<VehicleSuiteBusinessConfigDto>>(),
                    PageIndex = pageIndex,
                    PageSize = pageSize,
                    ServerTime = DateTime.Now
                };
            }, TimeSpan.FromMinutes(30));

            return result;
        }
        #endregion

        #region 启用车辆套餐业务配置
        public bool Enabled(AdminDto adminDto, int vehicleSuiteBusinessConfigId)
        {
            if (adminDto.AgentRecord == null)
            {
                throw new ArgumentException("非代理商无权修改此配置!");
            }
            if (!this.Exists(vehicleSuiteBusinessConfigId))
            {
                throw new ArgumentException("此记录不存在!");
            }
            var entity = this.Get(vehicleSuiteBusinessConfigId);
            if(entity.AgentRecordId != adminDto.AgentRecord.AgentRecordId)
            {
                throw new ArgumentException("您无权修改此配置!");
            }
            var result = this.vehicleSuiteBusinessConfigData.Enabled(vehicleSuiteBusinessConfigId, adminDto.AdminId, adminDto.FullName).GetAwaiter().GetResult();
            string cacheKey = this.redisService.GetKey(key, vehicleSuiteBusinessConfigId);
            this.redisService.DeleteAsync(cacheKey);
            return result;
        }
        #endregion

        #region 禁用车辆套餐业务配置
        public bool Disabled(AdminDto adminDto, int vehicleSuiteBusinessConfigId)
        {
            if (adminDto.AgentRecord == null)
            {
                throw new ArgumentException("非代理商无权修改此配置!");
            }
            if (!this.Exists(vehicleSuiteBusinessConfigId))
            {
                throw new ArgumentException("此记录不存在!");
            }
            var entity = this.Get(vehicleSuiteBusinessConfigId);
            if (entity.AgentRecordId != adminDto.AgentRecord.AgentRecordId)
            {
                throw new ArgumentException("您无权修改此配置!");
            }
            var result = this.vehicleSuiteBusinessConfigData.Disabled(vehicleSuiteBusinessConfigId, adminDto.AdminId, adminDto.FullName).GetAwaiter().GetResult();
            string cacheKey = this.redisService.GetKey(key, vehicleSuiteBusinessConfigId);
            this.redisService.DeleteAsync(cacheKey);
            return result;
        }
        #endregion
    }
}